#include "Communicator.h"
#include <iostream>
#include <curl/curl.h>
// 构造函数
Communicator::Communicator(const std::string& api_url, const std::string& api_key)
    : api_url_(api_url), api_key_(api_key) {
  std::cout << "[Communicator] Initialized with API URL: " << api_url_ << std::endl;
}

// 发送请求并返回响应
Response Communicator::SendRequest(const Request& request) {
  CURL* curl;
  CURLcode res;
  std::string response_data;
  // 将请求结构转换为 JSON 字符串
  std::string request_body = Protocol::SerializeRequest(request);

  // 初始化 CURL
  curl = curl_easy_init();
  if (curl) {
    // 设置请求头
    struct curl_slist* headers = nullptr;
    headers = curl_slist_append(headers, "Content-Type: application/json");
    headers = curl_slist_append(headers,
                                ("Authorization: Bearer " + api_key_).c_str());

    // 设置 CURL 选项
    curl_easy_setopt(curl, CURLOPT_URL, api_url_.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request_body.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data);

    // 执行请求
    std::cout << "[Communicator] Sending request to API..." << std::endl;
    res = curl_easy_perform(curl);
    if (res != CURLE_OK) {
      std::cerr << "[Communicator] curl_easy_perform() failed: "
                << curl_easy_strerror(res) << std::endl;
    }

    // 获取 HTTP 状态码
    long http_code = 0;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    std::cout << "[Communicator] HTTP Status Code: " << http_code << std::endl;

    // 打印响应数据
    std::cout << "[Communicator] API Response: " << response_data << std::endl;

    // 清理
    curl_easy_cleanup(curl);
    curl_slist_free_all(headers);
  } else {
    std::cerr << "[Communicator] Failed to initialize CURL." << std::endl;
  }

  // 解析响应
  return Protocol::ParseResponse(response_data);
}

// 回调函数，用于处理从服务器接收到的数据
size_t Communicator::WriteCallback(void* contents, size_t size, size_t nmemb,
                                   void* userp) {
  ((std::string*)userp)->append((char*)contents, size * nmemb);
  return size * nmemb;
}